<!DOCTYPE html>
<html lang="zh-CN">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Base64/十六进制转换工具</title>
    <style>
        body {
            font-family: Arial, sans-serif;
            max-width: 800px;
            margin: 0 auto;
            padding: 20px;
            line-height: 1.6;
        }
        .container {
            display: flex;
            flex-direction: column;
            gap: 20px;
        }
        textarea {
            width: 100%;
            min-height: 100px;
            padding: 10px;
            font-family: monospace;
            border: 1px solid #ccc;
            border-radius: 4px;
        }
        button {
            padding: 10px 15px;
            background-color: #4CAF50;
            color: white;
            border: none;
            border-radius: 4px;
            cursor: pointer;
            font-size: 16px;
        }
        button:hover {
            background-color: #45a049;
        }
        .button-group {
            display: flex;
            gap: 10px;
        }
        .button-group button {
            flex: 1;
        }
        .result-container {
            display: flex;
            flex-direction: column;
            gap: 10px;
        }
        .result-box {
            border: 1px solid #ddd;
            padding: 10px;
            background-color: #f9f9f9;
            border-radius: 4px;
            white-space: pre-wrap;
            word-break: break-all;
        }
        h2 {
            margin-top: 0;
            color: #333;
        }
        .error {
            color: red;
            font-weight: bold;
        }
        .options {
            display: flex;
            align-items: center;
            gap: 10px;
            margin: 10px 0;
        }
        .options label {
            display: flex;
            align-items: center;
            gap: 5px;
        }
        .tab-container {
            display: flex;
            border-bottom: 1px solid #ccc;
            margin-bottom: 20px;
        }
        .tab {
            padding: 10px 20px;
            cursor: pointer;
            border: 1px solid transparent;
            border-bottom: none;
            border-radius: 4px 4px 0 0;
            background-color: #f1f1f1;
        }
        .tab.active {
            background-color: #fff;
            border-color: #ccc;
            border-bottom: 1px solid #fff;
            margin-bottom: -1px;
        }
        .tab-content {
            display: none;
        }
        .tab-content.active {
            display: block;
        }

                 /* 黑夜模式 */
                 body.dark-mode h2,
            body.dark-mode .result-box,
            body.dark-mode .tab,
            body.dark-mode .tab.active {
                color: #ffffff;  /* 将文字颜色改为白色 */
            }
        body.dark-mode {
            background-color: #121212;
            color: #ffffff;
        }

        body.dark-mode .result-box {
            background-color: #1e1e1e;
            border-color: #333;
        }

        body.dark-mode .tab {
            background-color: #333;
            color: #fff;
        }

        body.dark-mode .tab.active {
            background-color: #444;
        }

        body.dark-mode textarea {
            background-color: #2d2d2d;
            color: #fff;
            border-color: #444;
        }
    /* 单div切换按钮样式 */
    .toggle-btn {
        position: fixed;
        top: 20px;
        right: 20px;
        z-index: 1000;
        width: 220px;
        height: 90px;
        background: 
                radial-gradient(circle at 18% 20px, #fff, #fff 6px, transparent 7px, transparent),
                radial-gradient(circle at 35% 45px, #fff, #fff 1px, transparent 2px, transparent),
                radial-gradient(circle at 10% 70px, #fff, #fff 2.5px, transparent 3.5px, transparent),
                radial-gradient(circle at 25% 15px, #fff, #fff 3px, transparent 4px, transparent),
                radial-gradient(circle at 15% 50px, #fff, #fff 1.5px, transparent 2.5px, transparent),
                radial-gradient(circle at 30% 75px, #fff, #fff 5px, transparent 6px, transparent),
                radial-gradient(circle at 5% 30px, #fff, #fff 0.5px, transparent 1.5px, transparent),
                radial-gradient(circle at 25% 60px, #fff, #fff 0.5px, transparent 1.5px, transparent),
                radial-gradient(circle at 7% 35px, #fff, #fff 0.5px, transparent 1.5px, transparent),
                linear-gradient(90deg, #2b303e, #2b303e 50%, #5a81b4 50%, #5a81b4);
        background-repeat: no-repeat;
        background-size: 200% 100%;
        background-position: 100% 0;
        border-radius: 90px;
        box-shadow: 
            0 -3px 4px #999,
            inset 0 3px 5px #333,
            0 4px 4px #ffe,
            inset 0 -3px 5px #ddd;
        cursor: pointer;
        overflow: hidden;
        transition: .5s all;
    }

    .toggle-btn::before,
    .toggle-btn::after {
        content: "";
        position: absolute;
        transition: .5s all;
    }

    .toggle-btn::before {
        width: 75px;
        height: 75px;
        border-radius: 50%;
        background: #e9cb50;
        inset: 7.5px;
        box-shadow: 
            0 0 5px #333,
            inset 2px 2px 3px #f8f4e4,
            inset -2px -2px 3px #665613;
        z-index: 1;
    }

    .toggle-btn::after {
        width: 70px;
        height: 70px;
        inset: 10px;
        border-radius: 50%;
        box-shadow: 
            10px 60px 0 10px #fff,
            65px 60px 0 5px #fff,
            95px 70px 0 10px #fff,
            135px 45px 0 5px #fff,
            170px 35px 0 10px #fff,
            195px -5px 0 10px #fff,
            -10px 0 0 50px rgba(255, 255, 255, .2),
            15px 0 0 50px rgba(255, 255, 255, .15),
            40px 0 0 50px rgba(255, 255, 255, .21),
            10px 40px 0 10px #abc1d9,
            70px 35px 0 10px #abc1d9,
            95px 40px 0 10px #abc1d9,
            135px 20px 0 10px #abc1d9,
            155px 15px 0 10px #abc1d9,
            190px -20px 0 10px #abc1d9;
    }

    .toggle-btn:hover::before {
        filter: contrast(90%) brightness(110%);
        scale: 1.05;
    }

    .toggle-btn.active {
        background-position: 0 0;
    }

    .toggle-btn.active::before {
        translate: 130px;
        background: 
            radial-gradient(circle at 50% 20px, #939aa5, #939aa5 6.5px, transparent 7px, transparent),
            radial-gradient(circle at 35% 45px, #939aa5, #939aa5 11.5px, transparent 12px, transparent),
            radial-gradient(circle at 72% 50px, #939aa5, #939aa5 8.5px, transparent 9px, transparent),
            radial-gradient(#cbcdda, #cbcdda);
    }

    .toggle-btn.active::after {
        transform: translate(130px);
        box-shadow: 
            10px 60px 0 10px transparent,
            65px 60px 0 5px transparent,
            95px 70px 0 10px transparent,
            135px 45px 0 5px transparent,
            170px 35px 0 10px transparent,
            195px -5px 0 10px transparent,
            10px 0 0 50px rgba(255, 255, 255, .2),
            -15px 0 0 50px rgba(255, 255, 255, .15),
            -40px 0 0 50px rgba(255, 255, 255, .21),
            10px 40px 0 10px transparent,
            70px 35px 0 10px transparent,
            95px 40px 0 10px transparent,
            135px 20px 0 10px transparent,
            155px 15px 0 10px transparent,
            190px -20px 0 10px transparent;
    }
    /* 缩小版按钮 */
    .toggle-btn {
        transform: scale(0.4);
        transform-origin: top right;
    }

</style>
</head>
<body>
    <h1>Base64/十六进制转换工具</h1>
    <div class="toggle-btn" id="g-btn"></div>
    
    <div class="tab-container">
        <div class="tab active" data-tab="hex-to-base64">十六进制转Base64</div>
        <div class="tab" data-tab="text-to-base64">文本转Base64</div>
    </div>
        
    
    
    <div class="container">
        
        <div class="tab-content active" id="hex-to-base64">
            <div>
                <h2>输入十六进制字符串</h2>
                <p>可以包含空格，如: <code>65 79 4a 7a 63 32 6c 6b 49 6a 6f 67 49 6a 45 79 4d 79 49 73 49 43 4a 77 59 58 4e 7a 64 32 39 79 5a 43 49 36 49 43 49 78 4d 6a 4d 69 4c 43 41 69 61 58 42 68 5a 47 52 79 49 6a 6f 67 49 6a 45 79 4d 79 4a 39</code></p>
                <textarea id="hexInput" placeholder="请输入十六进制字符串..."></textarea>
            </div>

            <button id="convertHexBtn">转换</button>
            
            <div class="result-container">
                <div>
                    <h2>hex转文本结果</h2>
                    <div id="hexToBase64Result" class="result-box">等待转换...</div>
                </div>
                
                <div>
                    <h2>文本转Base64</h2>
                    <div id="decodedTextResult" class="result-box">等待解码...</div>
                </div>
                
                <div>
                    <h2>JSON格式化结果</h2>
                    <div id="jsonResult" class="result-box">等待格式化...</div>
                </div>
            </div>
        </div>

        <div class="tab-content" id="text-to-base64">
            <div>
                <h2>输入文本</h2>
                <textarea id="textInput" placeholder='例如: {"ssid": "123", "password": "123", "ipaddr": "123"}'></textarea>
            </div>
            
            <div class="options">
                <label>
                    <input type="checkbox" id="addSpaces" checked>
                    输出添加空格分隔
                </label>
            </div>
            
            <button id="convertTextBtn">转换</button>
            
            <div class="result-container">
                <div>
                    <h2>Base64编码结果</h2>
                    <div id="base64Result" class="result-box">等待编码...</div>
                </div>
                
                <div>
                    <h2>Base64的十六进制表示</h2>
                    <div id="hexResult" class="result-box">等待转换...</div>
                </div>
                
                <div>
                    <h2>Base64的十进制表示</h2>
                    <div id="decimalResult" class="result-box">等待转换...</div>
                </div>
            </div>
        </div>
    </div>

    <script>
const toggleBtn = document.getElementById('g-btn');

        toggleBtn.addEventListener('click', function() {
        const isActive = this.classList.contains('active');
        this.classList.toggle('active');
        document.body.classList.toggle('dark-mode');
        
        // 保存用户偏好
        localStorage.setItem('darkMode', !isActive);
        });

        // 初始化时检查用户偏好
        if (localStorage.getItem('darkMode') === 'true') {
        document.body.classList.add('dark-mode');
        toggleBtn.classList.add('active');
        }
        // 标签页切换
        document.querySelectorAll('.tab').forEach(tab => {
            tab.addEventListener('click', function() {
                // 移除所有活动标签
                document.querySelectorAll('.tab').forEach(t => t.classList.remove('active'));
                document.querySelectorAll('.tab-content').forEach(c => c.classList.remove('active'));
                
                // 设置当前标签为活动状态
                this.classList.add('active');
                const tabId = this.getAttribute('data-tab');
                document.getElementById(tabId).classList.add('active');
            });
        });
        
        // 文本转Base64
        document.getElementById('convertTextBtn').addEventListener('click', function() {
            const textInput = document.getElementById('textInput').value.trim();
            const addSpaces = document.getElementById('addSpaces').checked;
            const base64Result = document.getElementById('base64Result');
            const hexResult = document.getElementById('hexResult');
            const decimalResult = document.getElementById('decimalResult');
            
            // 清空之前的结果
            base64Result.innerHTML = '等待编码...';
            hexResult.innerHTML = '等待转换...';
            decimalResult.innerHTML = '等待转换...';
            
            if (!textInput) {
                showError('请输入文本');
                return;
            }
            
            try {
                // 1. 首先将输入文本进行Base64编码
                const base64String = btoa(unescape(encodeURIComponent(textInput)));
                base64Result.textContent = base64String;
                
                // 2. 将Base64字符串转换为字节数组
                const byteArray = [];
                for (let i = 0; i < base64String.length; i++) {
                    byteArray.push(base64String.charCodeAt(i));
                }
                
                // 3. 生成十六进制表示
                const hexArray = [];
                for (const byte of byteArray) {
                    let hex = byte.toString(16);
                    // 补全2位
                    while (hex.length < 2) {
                        hex = '0' + hex;
                    }
                    hexArray.push(hex);
                }
                hexResult.textContent = addSpaces ? hexArray.join(' ') : hexArray.join('');
                
                // 4. 生成十进制表示
                decimalResult.textContent = addSpaces ? byteArray.join(' ') : byteArray.join('');
                
            } catch (e) {
                showError('转换过程中出错: ' + e.message);
            }
        });
        
        // 十六进制转Base64
        document.getElementById('convertHexBtn').addEventListener('click', function() {
            const hexInput = document.getElementById('hexInput').value.trim();
            const hexToBase64Result = document.getElementById('hexToBase64Result');
            const decodedTextResult = document.getElementById('decodedTextResult');
            const jsonResult = document.getElementById('jsonResult');
            
            // 清空之前的结果
            hexToBase64Result.innerHTML = '等待转换...';
            decodedTextResult.innerHTML = '等待解码...';
            jsonResult.innerHTML = '等待格式化...';
            
            if (!hexInput) {
                showError('请输入十六进制字符串');
                return;
            }
            
            try {
                // 处理十六进制字符串（移除空格）
                const cleanHex = hexInput.replace(/\s+/g, '');
                
                // 验证是否为有效的十六进制字符串
                if (!/^[0-9a-fA-F]+$/.test(cleanHex)) {
                    showError('输入包含非十六进制字符');
                    return;
                }
                
                // 十六进制转Base64字符串
                const base64String = hexToBase64(cleanHex);
                hexToBase64Result.textContent = base64String;
                
                // Base64解码
                try {
                    const decodedString = atob(base64String);
                    decodedTextResult.textContent = decodedString;
                    
                    // 尝试解析为JSON并格式化
                    try {
                        const jsonObj = JSON.parse(decodedString);
                        jsonResult.textContent = JSON.stringify(jsonObj, null, 2);
                    } catch (e) {
                        jsonResult.textContent = '不是有效的JSON格式';
                    }
                } catch (e) {
                    decodedTextResult.textContent = 'Base64解码失败: ' + e.message;
                }
            } catch (e) {
                showError('转换过程中出错: ' + e.message);
            }
        });
        
        function hexToBase64(hexString) {
            let result = '';
            for (let i = 0; i < hexString.length; i += 2) {
                const hex = hexString.substr(i, 2);
                result += String.fromCharCode(parseInt(hex, 16));
            }
            return result;
        }
        
        function showError(message) {
            const errorDiv = document.createElement('div');
            errorDiv.className = 'error';
            errorDiv.textContent = message;
            
            const container = document.querySelector('.container');
            container.insertBefore(errorDiv, container.firstChild);
            
            // 3秒后移除错误信息
            setTimeout(() => {
                if (errorDiv.parentNode) {
                    errorDiv.parentNode.removeChild(errorDiv);
                }
            }, 3000);
        }
    </script>
</body>
</html>

